home *** CD-ROM | disk | FTP | other *** search
- /* MainController.m
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- *
- * Written by Mai Nguyen, NeXT Developer Support
- *
- */
-
- #import "MainController.h"
- #import "Department.h"
- #import "strings.h"
-
- @implementation MainController
-
- - init
- {
- [super init];
- return self;
- }
-
- - appDidInit:sender
- {
-
- dbDataSource = [masterController dataSource];
- dbChannel = [dbDataSource databaseChannel];
- adaptorChannel = [dbChannel adaptorChannel];
- eoAdaptor = [[adaptorChannel adaptorContext] adaptor];
-
-
- // Bring up a login panel and get the valid connection dictionary
-
- if(![eoAdaptor runLoginPanelAndValidateConnectionDictionary])
- [NXApp terminate:self];
- [eoAdaptor setConnectionDictionary: [eoAdaptor connectionDictionary]];
-
- rootEntity = [dbDataSource entity];
-
- [self setDelegates];
-
- // set up the controller to not alter the selection after a fetch
- [masterController setSelectsFirstObjectAfterFetch:NO];
-
- [self fetch:sender];
- return self;
- }
-
- // Perform a fetch based on the latest options specified by user.
-
- - fetch:sender
- {
- if (optionsPanel)
- [optionsPanel orderOut:sender];
-
- [self setUpFetch:sender];
-
- [masterController fetch];
- return self;
- }
-
- - newRecord:sender
- {
- int i;
-
- // Clear all the current values in the form cells to prepare
- // for the insertion of a new record.
-
- for (i = 0; i < 5; i++)
- [formMatrix setStringValue:"" at:i];
- return self;
- }
-
- - insert:sender
- {
- // Disable the INSERT Button if the input is not valid
- if ([self validateRecord] == NO) {
- [insertButton setState:0];
- NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
- }
- else {
- [insertButton setState:1];
- [masterController insert:sender];
- }
- return self;
- }
-
-
- // Set up the fetch order and specify a qualifier
- // for the master table "Department"
-
- - setUpFetch:sender
- {
- const char *inputString;
- const char *attrName = NULL;
- EOQualifier *aQualifier;
- id fetchOrder;
- id sortAttribute;
- int orderType;
-
- // build the qualifier.
- // If the input string is empty, fetch all records.
-
- inputString = [(TextField *)textField stringValue];
-
- if (inputString == NULL)
- [dbDataSource setQualifier: [rootEntity qualifier]];
- else {
- aQualifier = [[[EOQualifier alloc] initWithEntity:rootEntity
- qualifierFormat:@"%A >= %d", @"DeptId",
- [textField intValue]] autorelease];
- [dbDataSource setQualifier:aQualifier];
- }
-
- // build the fetch order based on the first column of the master
- // tableview
-
- orderType = [sortMatrix selectedTag];
- attrName = [[masterTableview columnAt:0] title];
- sortAttribute = [rootEntity attributeNamed:[ [[NSString alloc]
- initWithCString:attrName] autorelease]];
- fetchOrder = [NSArray arrayWithObject:[[[EOAttributeOrdering alloc]
- initWithAttribute:sortAttribute ordering: orderType] autorelease]];
-
- [dbDataSource setFetchOrder:fetchOrder];
- return self;
- }
-
-
- - (BOOL) validateRecord
- {
- int newId, newLocation;
- BOOL result = YES;
-
- newId = [formMatrix intValueAt:0];
- newLocation = [formMatrix intValueAt:2];
-
- // Do validation here
- if ( newId < 100 || newId > 999) {
- NXRunAlertPanel(NULL, ERR_INVALID_ID, NULL, NULL, NULL);
- result = NO;
- }
- if ( newLocation != 1101 && newLocation != 1103
- && newLocation != 1104 && newLocation != 1106
- && newLocation != 1207) {
- NXRunAlertPanel(NULL, ERR_INVALID_LOCATION, NULL, NULL, NULL);
- result = NO;
- }
- return result;
-
- }
- - setDelegates
- {
- #ifdef DEBUG
- [adaptorChannel setDebugEnabled:YES];
- #endif
- [adaptorChannel setDelegate:self];
- [(EOController *) masterController setDelegate:self];
-
- return self;
- }
-
- @end
-
- @implementation MainController (EOAdaptorDelegation)
-
- //This method is useful to trace SQL queries
- - (void)adaptorChannel:channel
- didEvaluateExpression:(NSString *)expression
- {
- if (sqlPanel) {
- [text appendToText:"SQL Query:\n"];
- [text appendToText:[expression cString]];
- [text appendToText:"\n"];
- }
- }
- @end
-
-
- @implementation MainController (EOControllerDelegation)
-
- // This method is called before each update. Since the controller has
- // buffer edits turned ON, this method is called when the user explicitly
- // presses the UPDATE button.
-
- - (NSDictionary *)controller:(EOController *)controller
- willSaveEdits: (NSDictionary *)edits
- toObject:object
- {
- if ([self validateRecord] == YES)
- return edits;
- else {
- NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
- return nil;
- }
- }
-
- // Take the input from the formcells and create a new record.
- // This delegate method can be used to set up the default values of a newly
- // created EO. By default, we use the current user input in the formcells
- // to create a new record.
-
-
- - (BOOL)controller:(EOController *)controller willInsertObject:object atIndex: (unsigned)newIndex
- {
- [object setDeptId: (int)[formMatrix intValueAt:0]];
- [object setDepartmentName:[[[NSString alloc] initWithCString:
- [formMatrix stringValueAt:1]] autorelease]];
- [object setLocationId:(int)[formMatrix intValueAt:2]];
- // The to-many relationship points to an empty autoreleased array
- [object setToEmployee:[NSArray array]];
- return YES;
-
- }
-
- // After insertion, refetch object so that the derived attributes are
- // properly redisplayed.
-
- - (void)controller:(EOController *)controller didInsertObject:object
- inDataSource:dataSource
- {
- [dbChannel refetchObject:object];
- }
-
- // After an update, refetch object so that the derived attributes are
- // properly redisplayed.
-
- - (void)controller:(EOController *)controller didUpdateObject:object
- inDataSource:dataSource
- {
- [dbChannel refetchObject:object];
- }
-
- // When the insert operation failed, remove the wrong record and rollback
- // the data source. A failure usually happens when trying to insert a duplicate
- // key. Since an insert operation adds a new record after the current
- // selection, the index has to be computed accordingly.
-
-
- - (EODataSourceFailureResponse)controller:(EOController *)controller
- failedToInsertObject:object
- inDataSource:dataSource;
- {
- NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
-
- [controller deleteObjectAtIndex:([masterTableview selectedRow] + 1)];
-
- return EORollbackDataSourceFailureResponse;
- }
-
- - (EODataSourceFailureResponse) controller:(EOController *)controller
- failedToUpdateObject:object
- inDataSource:dataSource
- {
- NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
- // Restore object to its previous state
- [dbChannel refetchObject:object];
-
- return EORollbackDataSourceFailureResponse;
- }
-
-
- // When deleting a department, we need to null all the references
- // to that department. Therefore, the "toEmployee" relationship is
- // used to find the employee records attached to a given department.
- // All department ids will then be nulled out.
-
-
- - (BOOL)controller:controller willDeleteObject:object
- {
-
- NSArray *employeeArray = [object toEmployee];
- NSEnumerator *enumerator = [employeeArray objectEnumerator];
- EOGenericRecord *employee;
-
- while((employee = [enumerator nextObject]) != nil) {
- [employee setObject:[EONull null] forKey:@"DeptId"];
- [(id)[controller dataSource] updateObject:employee];
- }
-
- return YES;
- }
-
-
- // Implementing this delegate method allows the controller to discard
- // pending edits. In this example, pending edits are edits rejected by
- // the validation mechanism, hence they can be discarded.
-
- - (BOOL) controllerWillDiscardEdits:(EOController *)controller
- {
- return YES;
- }
-
- @end
-
- @implementation Text(printResults)
-
- - appendToText:(const char *)newText
- {
- int currentLength = [self textLength];
-
- [self setSel:currentLength :currentLength];
- [self replaceSel:newText];
- [self scrollSelToVisible];
- return self;
- }
-
- @end
-